package com.nexgo.payment.trans.mainfaceupload;

import android.support.annotation.NonNull;

import com.nexgo.payment.action.online.upload.Upload;
import com.nexgo.payment.aop.annotation.RunOnMainThread;
import com.nexgo.payment.aop.annotation.RunOnWorkThread;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.UploadType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.util.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 主界面上送
 * 离线/脱机类的交易循环上送最大复发次数，离线/脱机类的电子签名和上一笔联机电子签名则只上送一次
 * <p>
 * Created by xiaox on 2017/9/14.
 */
public class UploadPresenter implements UploadContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(UploadPresenter.class.getSimpleName());

    private UploadContract.View mView;
    private DataSource mRepository;
    private UploadType mUploadType;
    private boolean mIsFirstTime = true;
    private Upload.NowTask mTask = Upload.NowTask.MAG_OFFLINE;

    UploadPresenter(@NonNull UploadContract.View view, @NonNull DataSource repository, UploadType uploadType) {
        mView = checkNotNull(view);
        mRepository = checkNotNull(repository);
        mUploadType = uploadType;
        view.setPresenter(this);
    }

    @Override
    @RunOnWorkThread
    public void start() {
        if (mIsFirstTime) {
            if (UploadType.ES_ONLINE_LAST_BUT_NOT_CURRENT.equals(mUploadType)) {
                sendEsOnlineButNotCurrent();
            } else {
                sendOfflineLoopStart(true);
            }
            mIsFirstTime = false;
        }
    }

    @Override
    public void pause() {
    }

    @Override
    public void destroy() {

    }

    private Upload.OnUploadListener mUploadListener = new Upload.OnUploadListener() {

        @Override
        public void onShowTip(String tip) {
            postMainThread(() -> mView.showTip(tip));
        }

        @Override
        public void onUploadFailed() {
            quitUpload(false);
        }

        @Override
        public void onUploadComplete() {
            switch (mTask) {
                case ES_ONLINE_LAST_BUT_NOT_CURRENT:
                    quitUpload(true);
                    break;
                case MAG_OFFLINE:
                    sendIccOffline();
                    break;
                case ICC_OFFLINE:
                    doWhenOfflineUploadLoopEnds();
                    break;
                case ES_OFFLINE_NEVER_UPLOAD:
                default:
                    quitUpload(true);
                    break;
            }
        }
    };

    /**
     * 最后一笔联机非当前交易的电子签名
     */
    private void sendEsOnlineButNotCurrent() {
        mTask = Upload.NowTask.ES_ONLINE_LAST_BUT_NOT_CURRENT;
        Upload.getInstance(mTask, mRepository).sendTrans(mUploadListener);
    }

    /**
     * 离线/脱机交易上送一个大循环结束后的逻辑判断
     */
    private void doWhenOfflineUploadLoopEnds() {
        mLog.debug("离线上送一个大循环结束");
        //重发循环次数到了则发电子签名，否则开启下一次循环
        if (Upload.sUploadCounter < Integer.parseInt(StringUtils.firstNonEmpty(mRepository.getParamValue(PreferencesConstants.OFFLINE_TRANS_UPLOAD_TIMES), "3"))) {
            mLog.debug("继续循环上送");
            sendOfflineLoopStart(false);
        } else {
            sendEsOfflineNeverEverUpload();
        }
    }

    private void quitUpload(boolean isSuccussful) {
        postMainThread(() -> mView.setOnlineProcIndicator(false));
        postMainThread(() -> mView.quitUpload(isSuccussful));
    }

    /**
     * IC卡脱机上送
     */
    private void sendIccOffline() {
        mTask = Upload.NowTask.ICC_OFFLINE;
        Upload.getInstance(mTask, mRepository).sendTrans(mUploadListener);
    }

    /**
     * 磁条卡离线上送
     */
    private void sendMagOffline() {
        mTask = Upload.NowTask.MAG_OFFLINE;
        Upload.getInstance(mTask, mRepository).sendTrans(mUploadListener);
    }

    /**
     * 未上送过的离线/脱机电子签名上送
     */
    private void sendEsOfflineNeverEverUpload() {
        mTask = Upload.NowTask.ES_OFFLINE_NEVER_UPLOAD;
        Upload.getInstance(mTask, mRepository).sendTrans(mUploadListener);
    }

    /**
     * 开始上送离线/脱机交易
     *
     * @param firstTime 是否第一次
     */
    private void sendOfflineLoopStart(boolean firstTime) {
        initUploadCounter(firstTime);
        sendMagOffline();
    }

    private void initUploadCounter(boolean firstTime) {
        if (firstTime) {
            mLog.debug("初始上送计数器为1");
            Upload.sUploadCounter = 1;
        } else {
            Upload.sUploadCounter++;
            mLog.debug("上送计数器自增{}", Upload.sUploadCounter);
        }
    }

    @RunOnMainThread
    private void postMainThread(Runnable runnable) {
        runnable.run();
    }
}
